package platform.common.bo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import platform.common.dao.impl.CriticalTechnicalDaoException;
import platform.common.dao.impl.DaoException;
import platform.common.dao.impl.TechnicalDaoException;
import platform.common.exception.BusinessException;
import platform.common.exception.CriticalTechnicalException;
import platform.common.exception.InValidDataException;
import platform.common.exception.TechnicalException;
import platform.util.Util;

import com.google.gson.Gson;

import platform.common.bo.AbstractMemoryNestedSetTreeNode;
import platform.common.bo.IdentifiableObj;

public class MemoryNestedSetTree extends IdentifiableObj implements
		java.io.Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1751610201855026450L;
	private List<AbstractMemoryNestedSetTreeNode> listMemoryNestedSetTreeNode;

	/**
	 * 修改节点
	 * 
	 * @param treeNode
	 * @author guotingting
	 * @throws BusinessException
	 * @created date May 19, 2010
	 */
	public void updateTreeNode(AbstractMemoryNestedSetTreeNode treeNode)
			throws BusinessException {
		
		if(Util.isNull(treeNode)){
			throw new BusinessException("修改时未获取到节点");
		}
		if(Util.isNull(treeNode.getId())){
			throw new BusinessException("修改时未获取到节点id");
		}
		AbstractMemoryNestedSetTreeNode parent = getParent(treeNode.getId().toString());
		String parentId = parent.getId().toString();
		if(!Util.isNull(parent.getId())){
			parentId = parent.getId().toString();
		}else{
			parentId = null;
		}
		// 校验
		Map checkMap = checkBeforSave(treeNode,parentId);
		if (checkMap.size() > 0) {
			Gson gson = new Gson();
			throw new InValidDataException(gson.toJson(checkMap));
		}

		if (Util.isNull(treeNode)) {
			throw new BusinessException("修改时没有节点");
		}
		if (Util.isNull(treeNode.getId())) {
			throw new BusinessException("修改时没有节点id");
		}
		if (!isEmpty(listMemoryNestedSetTreeNode)) {
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode temp = listMemoryNestedSetTreeNode
						.get(i);
				if (temp.getId().toString().equals(treeNode.getId())) {
					listMemoryNestedSetTreeNode.set(i, treeNode);
					break;
				}
			}
		}
	}

	/**
	 * 获得本节点的孩子节点（即直接下级）
	 * 
	 * @throws BusinessException
	 */
	public List<AbstractMemoryNestedSetTreeNode> getChidren(String parentId)
			throws BusinessException {

		List listChild = new ArrayList(); // 孩子节点列表
		AbstractMemoryNestedSetTreeNode parent = null; // 父亲节点
		/**
		 * 查找父亲
		 */
		parent = findById(parentId);
		/**
		 * 获取父亲的左右值及深度
		 */
		int pLeft = parent.getLeftValue();
		int pRight = parent.getRightValue();
		int pTreeLeve = parent.getTreeLevel();
		int index = 0;
		/**
		 * 遍历集合,获取孩子
		 */
		if (!isEmpty(listMemoryNestedSetTreeNode)) { // 不为空,遍历listMemoryNestedSetTreeNode
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode child = listMemoryNestedSetTreeNode
						.get(i);
				// 如果集合中的元素的左值在父亲的左右值之间,并且深度等于父节点深度+1说明是它的孩子
				if (child.getLeftValue() > pLeft
						&& child.getRightValue() < pRight
						&& child.getTreeLevel() == (pTreeLeve + 1)) {
					listChild.add(index, child); // 将节点添加到孩子列表中
					index++;
				}
			}
		}

		return listChild;
	}

	/**
	 * 获得本节点的父节点（即直接上级）
	 * 
	 * @throws BusinessException
	 */
	public AbstractMemoryNestedSetTreeNode getParent(String childId)
			throws BusinessException {
		AbstractMemoryNestedSetTreeNode parent = null; // 父亲节点
		AbstractMemoryNestedSetTreeNode child = null; // 孩子节点
		/**
		 * 查找孩子
		 */
		child = findById(childId);
		/**
		 * 获取孩子的左右值及深度
		 */
		int cLeft = child.getLeftValue();
		int cRight = child.getRightValue();
		int cTreeLeve = child.getTreeLevel();

		/**
		 * 遍历集合,查找父亲
		 */
		if (!isEmpty(listMemoryNestedSetTreeNode)) { // 不为空,遍历listMemoryNestedSetTreeNode
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode tmpNode = listMemoryNestedSetTreeNode
						.get(i);
				// 如果集合中的元素的左值小于孩子节点的左值,右值大于孩子节点的右值,并且深度为孩子节点的深度+1,则为父亲节点
				if (tmpNode.getLeftValue() < cLeft
						&& tmpNode.getRightValue() > cRight
						&& tmpNode.getTreeLevel() == (cTreeLeve - 1)) {
					parent = tmpNode; // 取出父亲节点
				}
				break;
			}
		}
		return parent;
	}

	/**
	 * 获得本节点的后代节点（即子孙节点）
	 * 
	 * @param domainProviderSet
	 *            领域对象提供者集合
	 * @throws BusinessException
	 */
	public List<AbstractMemoryNestedSetTreeNode> getDescendants(String parentId)
			throws BusinessException {

		int index = 0; // 节点在list中的索引位置

		List listChild = new ArrayList(); // 孩子节点列表
		AbstractMemoryNestedSetTreeNode parent = null; // 父亲节点
		/**
		 * 查找父亲
		 */
		parent = findById(parentId);
		/**
		 * 获取父亲的左右值
		 */
		int pLeft = parent.getLeftValue();
		int pRight = parent.getRightValue();
		/**
		 * 遍历集合,获取孩子
		 */
		if (!isEmpty(listMemoryNestedSetTreeNode)) { // 不为空,遍历listMemoryNestedSetTreeNode
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode child = listMemoryNestedSetTreeNode
						.get(i);
				if (child.getLeftValue() > pLeft
						&& child.getRightValue() < pRight) { // 如果集合中的元素的左值在父亲的左右值之间
					listChild.add(index, child); // 将节点添加到孩子列表中
					index++;
				}
			}
		}

		return listChild;
	}

	/**
	 * 根据id查找节点
	 * 
	 * @return
	 * @throws BusinessException
	 * @author guotingting
	 * @created date May 17, 2010
	 */
	public AbstractMemoryNestedSetTreeNode findById(String id)
			throws BusinessException {
		AbstractMemoryNestedSetTreeNode treeNode = null;
		if (!isEmpty(listMemoryNestedSetTreeNode)) { // 不为空,遍历listMemoryNestedSetTreeNode
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode tmpNode = (AbstractMemoryNestedSetTreeNode) listMemoryNestedSetTreeNode
						.get(i);
				// 如果列表中节点的id与参数id相等,取出节点
				if (tmpNode.getId().toString().equals(id)) {
					treeNode = tmpNode;
					break;
				}
			}
		}
		if (treeNode == null) {
			throw new BusinessException("未找到记录");
		}
		return treeNode; // 返回节点
	}

	public void insertTreeNode(AbstractMemoryNestedSetTreeNode treeNode,
			String parentId) throws BusinessException {
		int leftValue = 1; // 初始化左值
		int rightValue = 2; // 初始化右值
		int treeLevel = 1;// 初始化深度
		int index = 0; // 新增节点在list中的索引位置
		int maxRight = 0; // 假设当前最大右值是0
		int limit = 0; // 界限值,取新插入节点前一个节点的右值,之后左右值大于此值的都要加2
		/**
		 * 插入到第一层节点的最后一个位置
		 */
		if (parentId == null) {
			if (!isEmpty(listMemoryNestedSetTreeNode)) { // 当前集合树不为空
				for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
					AbstractMemoryNestedSetTreeNode temp = listMemoryNestedSetTreeNode
							.get(i);
					if (temp.getTreeLevel() == 1) { // 获取第一级节点
						if (temp.getRightValue() > maxRight) { // 获取第一级节点的最大右值
							maxRight = temp.getRightValue();
							if (listMemoryNestedSetTreeNode.size() > 0) {
								index = listMemoryNestedSetTreeNode.size();
							} else {
								index = 0;
							}
						}
					}
				}
			}
			// 设置左右值及深度
			leftValue = maxRight + 1;
			rightValue = leftValue + 1;
			treeLevel = 1;
			/**
			 * 插入到子节点的最后一个位置
			 */
		} else {
			// 获取到父节点
			AbstractMemoryNestedSetTreeNode parent = null;
			try {
				parent = findById(parentId);
			} catch (BusinessException e) {
				throw new BusinessException("未找到父节点");
			}
			AbstractMemoryNestedSetTreeNode lastNode = null; // 存放最小兄弟节点
			List listChild = getChidren(parentId); // 获取到所有孩子节点
			/**
			 * 获取最小兄弟节点
			 */
			if (!isEmpty(listChild)) {
				int lastIndex = 0;
				if (listChild.size() > 0) {
					lastIndex = listChild.size() - 1;
					lastNode = (AbstractMemoryNestedSetTreeNode) listChild
							.get(lastIndex);
				}
				/**
				 * lastNode如果不为空,说明其父下已经有孩子,将其放在最后一个位置
				 */
				if (lastNode != null) {
					leftValue = lastNode.getRightValue() + 1; // 左值为最后一个节点左值+2
					rightValue = leftValue + 1;// 右值
					treeLevel = parent.getTreeLevel() + 1; // 深度

					int numOfChild = (lastNode.getRightValue()
							- lastNode.getLeftValue() - 1) / 2;

					index = listMemoryNestedSetTreeNode.indexOf(lastNode)
							+ numOfChild + 1; // 在list中的索引位置为最后一个节点的位置+1
				}
				/**
				 * lastNode如果为空,说明其父下没有孩子,直接放在其父节点下
				 */
				else {
					leftValue = parent.getLeftValue() + 1;// 左值为父节点左值+1
					rightValue = leftValue + 1; // 右值
					treeLevel = parent.getTreeLevel() + 1; // 深度
					index = listMemoryNestedSetTreeNode.indexOf(parent) + 1; // 在list中的索引位置为父节点的索引位置+1
				}
			}
		}

		// 设置左右值及深度
		treeNode.setLeftValue(leftValue);
		treeNode.setRightValue(rightValue);
		treeNode.setTreeLevel(treeLevel);
		/**
		 * 修改其他节点的左右值及深度
		 */
		if (!isEmpty(listMemoryNestedSetTreeNode)) {
			limit = leftValue - 1;
			/**
			 * 修改左值
			 */
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode temp = listMemoryNestedSetTreeNode
						.get(i);
				if (temp.getLeftValue() > limit) {
					temp.setLeftValue(temp.getLeftValue() + 2);
					listMemoryNestedSetTreeNode.set(i, temp); // list.set(int
				}
			}
			/**
			 * 修改右值
			 */
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode temp = listMemoryNestedSetTreeNode
						.get(i);
				if (temp.getRightValue() > limit) {
					temp.setRightValue(temp.getRightValue() + 2);
					listMemoryNestedSetTreeNode.set(i, temp); // list.set(int
				}
			}
		}

		// 校验
		Map checkMap = checkBeforSave(treeNode,parentId);
		if (checkMap.size() > 0) {
			Gson gson = new Gson();
			throw new InValidDataException(gson.toJson(checkMap));
		}
		// 将自己插入到列表中
		if (isEmpty(listMemoryNestedSetTreeNode)) {
			listMemoryNestedSetTreeNode = new ArrayList();
		}
		listMemoryNestedSetTreeNode.add(index, treeNode);

	}

	/**
	 * 删除节点,删除的必须是子节点
	 * 
	 * @param treeNode
	 * @author guotingting
	 * @throws BusinessException
	 * @created date May 18, 2010
	 */
	public void deleteTreeNode(String id) throws BusinessException {
		AbstractMemoryNestedSetTreeNode treeNode = null;
		treeNode = findById(id);
		int leftValue = treeNode.getLeftValue(); // 左值
		int rightValue = treeNode.getRightValue(); // 右值
		// 如果不是叶子节点,抛出异常
		if (rightValue - leftValue > 1) {
			throw new BusinessException("必须是叶子节点");
		}
		/**
		 * 顶级科目不允许删除
		 */
		if (treeNode.getTreeLevel() == 1) {
			throw new BusinessException("顶级科目不允许删除");
		}
		for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
			AbstractMemoryNestedSetTreeNode temp = listMemoryNestedSetTreeNode
					.get(i);
			if (temp.getLeftValue() > rightValue) {
				temp.setLeftValue(temp.getLeftValue() - 2);
				listMemoryNestedSetTreeNode.set(i, temp);
			}
		}
		for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
			AbstractMemoryNestedSetTreeNode temp = listMemoryNestedSetTreeNode
					.get(i);
			if (temp.getRightValue() > rightValue) {
				temp.setRightValue(temp.getRightValue() - 2);
				listMemoryNestedSetTreeNode.set(i, temp);
			}
		}
		listMemoryNestedSetTreeNode.remove(treeNode);
	}

	/**
	 * 
	 * 方法功能描述:新增前校验 //todo
	 * 
	 * @return
	 * @author guotingting
	 * @throws BusinessException
	 * @created date May 20, 2010
	 */
	public Map checkBeforSave(AbstractMemoryNestedSetTreeNode treeNode,
			String parentId) throws BusinessException {
		Map map = new HashMap(); // 返回验证结果集
		/**
		 * 名称为空验证
		 */
		if(Util.isNull(treeNode.getName())){
			map.put("name", "名称不能为空");
			return map;
		}
		
		List checkList = new ArrayList(); // 需要验证的范围列表
		if (Util.isNull(parentId)) { // 如果父节点为空,在顶级科目中验证
			for (int i = 0; i < listMemoryNestedSetTreeNode.size(); i++) {
				AbstractMemoryNestedSetTreeNode temp = listMemoryNestedSetTreeNode
						.get(i);
				if (temp.getTreeLevel() == 1) {
					checkList.add(temp);
				}
			}
		} 
		else {// 如果父节点为空,在直接下级中验证
			checkList = getChidren(parentId);
		}
			for (int i = 0; i < checkList.size(); i++) {
				AbstractMemoryNestedSetTreeNode checkNode = (AbstractMemoryNestedSetTreeNode) checkList
						.get(i);
				if (checkNode.getName().equals(treeNode.getName()) //名称相同且id不同,认为是重名的
						&& !checkNode.getId().toString().equals(
								treeNode.getId().toString())) {
					map.put("name", "同级下名称不能重复");
					break;
				}
			}
		return map;
	}

	/**
	 * 方法功能描述 :判断树的集合是否为空
	 * 
	 * @return true :为空 false:不为空
	 * @author guotingting
	 */
	private boolean isEmpty(List list) {
		if (list != null) {
			return false;
		}
		return true;
	}

	public List<AbstractMemoryNestedSetTreeNode> getListMemoryNestedSetTreeNode() {
		return listMemoryNestedSetTreeNode;
	}

	public void setListMemoryNestedSetTreeNode(
			List<AbstractMemoryNestedSetTreeNode> listMemoryNestedSetTreeNode) {
		this.listMemoryNestedSetTreeNode = listMemoryNestedSetTreeNode;
	}

}
